package com.cal.utms.model.payment;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.cal.utms.action.user_maintenance.LoginAction;
import com.cal.utms.dao.maintenance.CustomerDaoImpl;
import com.cal.utms.dao.maintenance.NewFundDao;
import com.cal.utms.dao.payment.InvestmentDaoImpl;
import com.cal.utms.dao.payment.PledgeDaoImpl;
import com.cal.utms.dao.payment.RedemptionDaoImpl;
import com.cal.utms.dao.user_maintenance.UserDaoImpl;
import com.cal.utms.dto.payment.InvestmentDto;
import com.cal.utms.dto.payment.InvestmentForPledge;
import com.cal.utms.dto.payment.RedemptionInvestmentDto;
import com.cal.utms.entity.CustomerInvestment;
import com.cal.utms.entity.CustomerRedemptionRequest;
import com.cal.utms.entity.CustomerTransactionLog;
import com.cal.utms.entity.Fund;
import com.cal.utms.entity.MoneyTransaction;
import com.cal.utms.entity.Receipt;
import com.cal.utms.entity.RedemptionReqToRedemtion;
import com.cal.utms.enumType.DepositType;
import com.cal.utms.enumType.FundTransferType;
import com.cal.utms.model.maintenance.HolidayModel;
import com.cal.utms.util.NextDate;
import com.cal.utms.util.Sequence;
import com.cal.utms.util.ValueConvert;

public class InvestmentModel {
	HolidayModel holidayModel = new HolidayModel();
	InvestmentDaoImpl daoImpl = new InvestmentDaoImpl();
	CustomerDaoImpl customerDao = new CustomerDaoImpl();
	UserDaoImpl userDaoImpl = new UserDaoImpl();
	NewFundDao fundDao = new NewFundDao();
	MoneyTransactionModel moneyTransactionModel = new MoneyTransactionModel();
	RedemptionDaoImpl redemptionDaoImpl = new RedemptionDaoImpl();

	SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);
	DecimalFormat amountFormatter = new DecimalFormat("#,###.00");
	DecimalFormat valueFormatter = new DecimalFormat("#,###.0000");

	public List<InvestmentDto> createInvestmentBeanList() {
		List<CustomerInvestment> customerInvestments = daoImpl.getInvestmentList();
		List<InvestmentDto> investmentBeans = new ArrayList<InvestmentDto>();
		InvestmentDto investment = null;
		for (CustomerInvestment customerInvestment : customerInvestments) {
			investment = new InvestmentDto();
			investment.setAmount(amountFormatter.format(customerInvestment.getAmount().doubleValue()));
			investment.setDepositTo(customerInvestment.getDepositTo().toString());
			investment.setFullRedemption(customerInvestment.getFullRedemption());
			if (customerInvestment.getFullRedemptionDate() != null)
				investment.setFullRedemptionDate(format.format(customerInvestment.getFullRedemptionDate()));
			investment.setFundTransferType(customerInvestment.getFundTransferType().toString());
			investment.setInvenstmentCode(customerInvestment.getInvenstmentCode());
			if (customerInvestment.getMonIntStartDate() != null)
				investment.setMonIntStartDate(format.format(customerInvestment.getMonIntStartDate()));
			investment.setMonthlyInterestRequired(customerInvestment.getMonthlyInterestRequired());
			if (customerInvestment.getRequestDate() != null)
				investment.setRequestDate(format.format(customerInvestment.getRequestDate()));
			if (customerInvestment.getInterestType() != null)
				investment.setInvestmentinterestType(customerInvestment.getInterestType());
			investment.setStatus(customerInvestment.getStatus());
			investment.setId(customerInvestment.getId());
			investment.setCustomer(customerInvestment.getCustomer().getId());
			if (customerInvestment.getCustomer().getDenotedByInitials() != null) {
				investment.setCustomer_name(customerInvestment.getCustomer().getDenotedByInitials() + " " + customerInvestment.getCustomer().getSurname());
			} else {
				investment.setCustomer_name(customerInvestment.getCustomer().getSurname());
			}
			if (customerInvestment.getFundTransferType() == FundTransferType.C) {
				investment.setNameOfBank(customerInvestment.getNameOfBank());
				investment.setChequeNo(customerInvestment.getChequeNo());
				if (customerInvestment.getChequeDate() != null)
					investment.setChequeDate(format.format(customerInvestment.getChequeDate()));
				investment.setBranch(customerInvestment.getBranch());
			}
			if (customerInvestment.getFundTransferType() == FundTransferType.R || customerInvestment.getFundTransferType() == FundTransferType.S) {
				investment.setAccountNo(customerInvestment.getCustomerBankAccount().getId());
			}
			investment.setRecodUser(customerInvestment.getRecodeUser().getId());
			if (customerInvestment.getFund() != null) {
				investment.setFund_id(customerInvestment.getFund().getId());
				if (investment.getStatus().equals("INITIAL")) {
					String unitval = amountFormatter.format(customerInvestment.getFund().getUnitValue());
					investment.setUnitPrice(unitval);
					investment.setNoOfUnits(valueFormatter.format(customerInvestment.getAmount().doubleValue() / customerInvestment.getFund().getUnitValue().doubleValue()));
					investment.setConfirmDate(format.format(customerInvestment.getFund().getUpdateDate()));
				} else {
					if (customerInvestment.getIssuedDate() != null)
						investment.setConfirmDate(format.format(customerInvestment.getIssuedDate()));
					if (customerInvestment.getIssuedUnitPrice() != null)
						investment.setUnitPrice(customerInvestment.getIssuedUnitPrice().toString());
					if (customerInvestment.getNoOfIssuedUnit() != null)
						investment.setNoOfUnits(customerInvestment.getNoOfIssuedUnit().toString());
				}
			}
			if (customerInvestment.getInstructions() != null) {
				investment.setInstructions(customerInvestment.getInstructions());
			}
			investmentBeans.add(investment);
		}

		return investmentBeans;
	}

	public List<InvestmentDto> getAllInitalInvestment() {
		List<CustomerInvestment> customerInvestments = daoImpl.getAllInitalInvestmentList();
		List<InvestmentDto> investmentBeans = new ArrayList<InvestmentDto>();
		InvestmentDto investment = null;
		for (CustomerInvestment customerInvestment : customerInvestments) {
			investment = new InvestmentDto();
			investment.setAmount(amountFormatter.format(customerInvestment.getAmount().doubleValue()));
			investment.setDepositTo(customerInvestment.getDepositTo().toString());
			investment.setFullRedemption(customerInvestment.getFullRedemption());
			if (customerInvestment.getFullRedemptionDate() != null)
				investment.setFullRedemptionDate(format.format(customerInvestment.getFullRedemptionDate()));
			investment.setFundTransferType(customerInvestment.getFundTransferType().toString());
			investment.setInvenstmentCode(customerInvestment.getInvenstmentCode());
			if (customerInvestment.getMonIntStartDate() != null)
				investment.setMonIntStartDate(format.format(customerInvestment.getMonIntStartDate()));
			investment.setMonthlyInterestRequired(customerInvestment.getMonthlyInterestRequired());
			if (customerInvestment.getRequestDate() != null)
				investment.setRequestDate(format.format(customerInvestment.getRequestDate()));
			if (customerInvestment.getInterestType() != null)
				investment.setInvestmentinterestType(customerInvestment.getInterestType());
			investment.setStatus(customerInvestment.getStatus());
			investment.setId(customerInvestment.getId());
			investment.setCustomer(customerInvestment.getCustomer().getId());
			if (customerInvestment.getCustomer().getDenotedByInitials() != null) {
				investment.setCustomer_name(customerInvestment.getCustomer().getDenotedByInitials() + " " + customerInvestment.getCustomer().getSurname());
			} else {
				investment.setCustomer_name(customerInvestment.getCustomer().getSurname());
			}
			if (customerInvestment.getFundTransferType() == FundTransferType.C) {
				investment.setNameOfBank(customerInvestment.getNameOfBank());
				investment.setChequeNo(customerInvestment.getChequeNo());
				if (customerInvestment.getChequeDate() != null)
					investment.setChequeDate(format.format(customerInvestment.getChequeDate()));
				investment.setBranch(customerInvestment.getBranch());
			}
			if (customerInvestment.getFundTransferType() == FundTransferType.R || customerInvestment.getFundTransferType() == FundTransferType.S) {
				investment.setAccountNo(customerInvestment.getCustomerBankAccount().getId());
			}
			investment.setRecodUser(customerInvestment.getRecodeUser().getId());
			if (customerInvestment.getFund() != null) {
				investment.setFund_id(customerInvestment.getFund().getId());
				if (investment.getStatus().equals("INITIAL")) {
					String unitval = amountFormatter.format(customerInvestment.getFund().getUnitValue());
					investment.setUnitPrice(unitval);
					investment.setNoOfUnits(valueFormatter.format(customerInvestment.getAmount().doubleValue() / customerInvestment.getFund().getUnitValue().doubleValue()));
					investment.setConfirmDate(format.format(customerInvestment.getFund().getUpdateDate()));
				} else {
					if (customerInvestment.getIssuedDate() != null)
						investment.setConfirmDate(format.format(customerInvestment.getIssuedDate()));
					if (customerInvestment.getIssuedUnitPrice() != null)
						investment.setUnitPrice(customerInvestment.getIssuedUnitPrice().toString());
					if (customerInvestment.getNoOfIssuedUnit() != null)
						investment.setNoOfUnits(customerInvestment.getNoOfIssuedUnit().toString());
				}
			}
			if (customerInvestment.getInstructions() != null) {
				investment.setInstructions(customerInvestment.getInstructions());
			}
			investmentBeans.add(investment);
		}

		return investmentBeans;

	}

	public void saveInvestment(InvestmentDto investmentBean) {

		CustomerInvestment customerInvestment = createInvestmentModule(investmentBean);
		Object object = daoImpl.addCustomerInvestment(customerInvestment);
		if (object instanceof Integer) {
			investmentBean.setId((Integer) object);
			investmentBean.setSuccess(true);
			investmentBean.setResulteMsg("SUCCESS");
		} else {
			investmentBean.setSuccess(false);
			investmentBean.setResulteMsg("There is some error returned from the server.");
		}

	}

	private CustomerInvestment createInvestmentModule(InvestmentDto investmentBean) {
		CustomerInvestment customerInvestment = new CustomerInvestment();

		Sequence seq = new Sequence();

		if (investmentBean.getAmount() != null) {
			String amount = investmentBean.getAmount().replaceAll(",", "");
			double d = Double.parseDouble(amount);
			customerInvestment.setAmount(BigDecimal.valueOf(d));
		}
		if (investmentBean.getDepositTo() != null) {
			if (investmentBean.getDepositTo().equals("N"))
				customerInvestment.setDepositTo(DepositType.N);
			else
				customerInvestment.setDepositTo(DepositType.C);
		} else {
			customerInvestment.setDepositTo(DepositType.C);
		}
		customerInvestment.setFullRedemption(investmentBean.getFullRedemption());
		if (investmentBean.getFundTransferType().equals("R"))
			customerInvestment.setFundTransferType(FundTransferType.R);
		else if (investmentBean.getFundTransferType().equals("S"))
			customerInvestment.setFundTransferType(FundTransferType.S);
		else if (investmentBean.getFundTransferType().equals("T"))
			customerInvestment.setFundTransferType(FundTransferType.T);
		else if (investmentBean.getFundTransferType().equals("C")) {
			customerInvestment.setFundTransferType(FundTransferType.C);
			customerInvestment.setNameOfBank(investmentBean.getNameOfBank());
			customerInvestment.setBranch(investmentBean.getBranch());
			customerInvestment.setChequeNo(investmentBean.getChequeNo());
			if (investmentBean.getChequeDate() != null)
				try {
					customerInvestment.setChequeDate(format.parse(investmentBean.getChequeDate()));
				} catch (ParseException e) {
					e.printStackTrace();
				}
		}
		customerInvestment.setInvenstmentCode("INV" + seq.getNextValue("INVESTMENT"));
		customerInvestment.setMonthlyInterestRequired(investmentBean.getMonthlyInterestRequired());
		if (investmentBean.getMonthlyInterestRequired() == 1) {
			customerInvestment.setInterestType(investmentBean.getInvestmentinterestType());
		}
		try {
			customerInvestment.setRequestDate(format.parse(investmentBean.getRequestDate()));
			if (investmentBean.getFullRedemptionDate() != null)
				customerInvestment.setFullRedemptionDate(format.parse(investmentBean.getFullRedemptionDate()));
			if (investmentBean.getMonIntStartDate() != null)
				customerInvestment.setMonIntStartDate(format.parse(investmentBean.getMonIntStartDate()));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		customerInvestment.setStatus(investmentBean.getStatus());
		customerInvestment.setCustomer(customerDao.getCustomerById(investmentBean.getCustomer()));
		customerInvestment.setCustomerBankAccount(customerDao.getAccountById(investmentBean.getAccountNo()));
		customerInvestment.setRecodeUser(LoginAction.getCurrentLogingUser());
		customerInvestment.setRecodeDate(new Date());
		customerInvestment.setPostStatus("NOT POST");
		customerInvestment.setPostAddress("Corresponding Address");
		if (investmentBean.getInstructions() != null) {
			customerInvestment.setInstructions(investmentBean.getInstructions());
		}

		if (investmentBean.getFund_id() != 0) {
			try {
				customerInvestment.setFund(fundDao.getById(investmentBean.getFund_id()));
				if (investmentBean.getConfirmDate() != null || investmentBean.getConfirmDate() != "")
					customerInvestment.setIssuedDate(format.parse(investmentBean.getConfirmDate()));
				if (investmentBean.getUnitPrice() != null) {
					String amount = investmentBean.getUnitPrice().replaceAll(",", "");
					double d = Double.parseDouble(amount);
					customerInvestment.setIssuedUnitPrice(BigDecimal.valueOf(d));
				}
				if (investmentBean.getNoOfUnits() != null) {
					String amount = investmentBean.getNoOfUnits().replaceAll(",", "");
					double d = Double.parseDouble(amount);
					customerInvestment.setNoOfIssuedUnit(BigDecimal.valueOf(d));
					customerInvestment.setBalanceUnits(BigDecimal.valueOf(d));
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		return customerInvestment;
	}

	public void updateInvestment(InvestmentDto investmentBean, int investment_id) {

		CustomerInvestment perInvestment = daoImpl.getInvesmentByCode(investmentBean.getInvenstmentCode());
		if (perInvestment.getId() != investment_id) {
			investmentBean.setSuccess(false);
			investmentBean.setResulteMsg("Investment Code already exists");
		} else {
			CustomerInvestment customerInvestment = createInvestmentModule(investmentBean);
			customerInvestment.setId(investment_id);
			daoImpl.updateCustomerInvestment(customerInvestment);
			investmentBean.setSuccess(true);
			investmentBean.setResulteMsg("SUCCESS");
		}
	}

	public void confirm(InvestmentDto investmentBean, int investment_id) {
		double amount_d = 0;

		CustomerInvestment perInvestment = daoImpl.getById(investment_id);
		if (investmentBean.getAmount() != null) {
			String amount = investmentBean.getAmount().replaceAll(",", "");
			amount_d = Double.parseDouble(amount);
			DecimalFormat df = new DecimalFormat("#.00");
			BigDecimal decimal = ValueConvert.toBigDecimal(df.format(amount_d));
			if (perInvestment.getAmount().compareTo(decimal) != 0) {
				investmentBean.setSuccess(false);
				investmentBean.setResulteMsg("Amount not consistent with requested amount");
			} else {
				perInvestment = createInvModule(investmentBean, perInvestment);
				perInvestment.setId(investment_id);

				if (!perInvestment.getFundTransferType().equals(FundTransferType.C)) {
					/* Create Money Transaction record */
					List<MoneyTransaction> moneyTransactions = moneyTransactionModel.getInvestmetTransaction(investmentBean.getConfirmDate(), investment_id,
							investmentBean.getAmount(), investmentBean.getCustomer(), investmentBean.getFund_id());

					/* Create Full Redemption Request */
					CustomerRedemptionRequest redemptionRequest = null;
					if (investmentBean.getFullRedemption() == 1) {
						redemptionRequest = createRedemtioReqest(perInvestment);
					}

					/* Create Monthly Redemption Request */
					CustomerRedemptionRequest monthlyRedempRequest = null;
					if (investmentBean.getMonthlyInterestRequired() == 1) {
						NextDate nextDate = new NextDate();
						monthlyRedempRequest = createMonthlyRedemtioReqest(perInvestment);
						perInvestment.setMonIntNextDate(nextDate.getNextDate(perInvestment.getMonIntStartDate(), perInvestment.getInterestType()));
					}

					/* Receipt generation */
					Receipt receipt = null;
					receipt = createReceip(perInvestment);

					/* Customer Transaction log */
					CustomerTransactionLog customerTransactionLog = createTransactionLog(perInvestment);

					perInvestment.setReceipt(receipt);

					daoImpl.confirmCustomerInvestment(perInvestment, moneyTransactions, redemptionRequest, null, monthlyRedempRequest, customerTransactionLog);
					investmentBean.setSuccess(true);
					investmentBean.setResulteMsg("SUCCESS");
				} else {
					Receipt receipt = null;
					receipt = createReceip(perInvestment);
					perInvestment.setReceipt(receipt);
					daoImpl.confirmCustomerInvestment(perInvestment, null, null, null, null, null);
					investmentBean.setSuccess(true);
					investmentBean.setResulteMsg("SUCCESS");
				}

			}
		}

	}

	private CustomerTransactionLog createTransactionLog(CustomerInvestment perInvestment) {
		CustomerTransactionLog customerTransactionLog = new CustomerTransactionLog();
		customerTransactionLog.setCustomer(perInvestment.getCustomer());
		customerTransactionLog.setFund(perInvestment.getFund());
		customerTransactionLog.setTranType("INVESTMENT");
		customerTransactionLog.setTranUnits(perInvestment.getNoOfIssuedUnit());
		customerTransactionLog.setCustomerInvestment(perInvestment);
		customerTransactionLog.setUser(LoginAction.getCurrentLogingUser());
		return customerTransactionLog;
	}

	private CustomerRedemptionRequest createMonthlyRedemtioReqest(CustomerInvestment perInvestment) {

		Sequence seq = new Sequence();
		CustomerRedemptionRequest request = new CustomerRedemptionRequest();
		List<RedemptionReqToRedemtion> redemtions = new ArrayList<RedemptionReqToRedemtion>();

		request.setCustomer(perInvestment.getCustomer());
		request.setRedemptionCode("RED" + seq.getNextValue("REDEMPTION"));
		request.setRedemptionType("V");

		request.setTotUnit(BigDecimal.ZERO);
		request.setTotAmount(BigDecimal.ZERO);
		request.setRequestDate(perInvestment.getRequestDate());
		request.setRedemUnitPrice(BigDecimal.ZERO);
		request.setExpectedDate(perInvestment.getMonIntStartDate());
		request.setStatus("INITIAL");
		request.setFund(perInvestment.getFund());
		request.setRecordUser(LoginAction.getCurrentLogingUser().getId());
		request.setRecordDate(new Date());
		request.setRecordType("M");

		RedemptionReqToRedemtion redemtion = new RedemptionReqToRedemtion();
		redemtion.setCustomerRedemptionRequest(request);
		redemtion.setReleaseUnits(BigDecimal.ZERO);
		redemtion.setReleaseAmount(BigDecimal.ZERO);
		redemtion.setBalance(BigDecimal.ZERO);
		redemtion.setCustomerInvestment(perInvestment);
		redemtions.add(redemtion);

		request.setRedemptionReqToRedemtions(redemtions);
		return request;
	}

	private Receipt createReceip(CustomerInvestment perInvestment) {
		Receipt receipt = new Receipt();
		Sequence seq = new Sequence();
		receipt.setAmount(perInvestment.getAmount());
		receipt.setReceiptNo("REC" + seq.getNextValue("RECEIPT"));
		receipt.setCustomerId(perInvestment.getCustomer().getId());
		receipt.setCustomerType("CUS");
		receipt.setPaymentType(perInvestment.getFundTransferType().toString());
		receipt.setFund(perInvestment.getFund());
		receipt.setDepositAccount(perInvestment.getDepositTo().toString());
		receipt.setReqDate(perInvestment.getIssuedDate());
		receipt.setReqUserId(LoginAction.getCurrentLogingUser().getId());
		// if (perInvestment.getFundTransferType() == FundTransferType.C) {
		// receipt.setChequeDate(perInvestment.getChequeDate());
		// receipt.setChequeNo(perInvestment.getChequeNo());
		// receipt.setBankName(perInvestment.getNameOfBank());
		// } else if (perInvestment.getFundTransferType() == FundTransferType.R
		// || perInvestment.getFundTransferType() == FundTransferType.S) {
		// receipt.setBankAccount(perInvestment.getCustomerBankAccount().getAccountNo());
		// receipt.setBankName(perInvestment.getCustomerBankAccount().getNameOfBank());
		// receipt.setBankId(perInvestment.getCustomerBankAccount().getId());
		// }
		return receipt;
	}

	private CustomerRedemptionRequest createRedemtioReqest(CustomerInvestment investmentBean) {

		Sequence seq = new Sequence();
		CustomerRedemptionRequest request = new CustomerRedemptionRequest();
		List<RedemptionReqToRedemtion> redemtions = new ArrayList<RedemptionReqToRedemtion>();

		request.setCustomer(investmentBean.getCustomer());
		request.setRedemptionCode("RED" + seq.getNextValue("REDEMPTION"));
		request.setRedemptionType("U");
		request.setTotAmount(BigDecimal.ZERO);
		request.setRedemUnitPrice(BigDecimal.ZERO);
		request.setTotUnit(investmentBean.getNoOfIssuedUnit());
		request.setRequestDate(investmentBean.getRequestDate());
		request.setExpectedDate(investmentBean.getFullRedemptionDate());
		request.setStatus("INITIAL");
		request.setFund(investmentBean.getFund());
		request.setRecordUser(LoginAction.getCurrentLogingUser().getId());
		request.setRecordDate(new Date());
		request.setRecordType("F");

		RedemptionReqToRedemtion redemtion = new RedemptionReqToRedemtion();
		redemtion.setCustomerRedemptionRequest(request);
		redemtion.setReleaseUnits(investmentBean.getNoOfIssuedUnit());
		redemtion.setReleaseAmount(BigDecimal.ZERO);
		redemtion.setBalance(BigDecimal.ZERO);
		redemtion.setCustomerInvestment(investmentBean);
		redemtions.add(redemtion);

		request.setRedemptionReqToRedemtions(redemtions);
		return request;
	}

	private CustomerInvestment createInvModule(InvestmentDto investmentBean, CustomerInvestment customerInvestment) {
		if (investmentBean.getFund_id() != 0) {
			if (investmentBean.getFundTransferType().equals("C"))
				customerInvestment.setStatus("UNREALISED");
			else
				customerInvestment.setStatus("CONFIRM");
			customerInvestment.setIssuedUser(LoginAction.getCurrentLogingUser());
			Fund fund = fundDao.getById(investmentBean.getFund_id());
			customerInvestment.setFund(fund);
			customerInvestment.setIssuedDate(fund.getUpdateDate());
			if (investmentBean.getUnitPrice() != null) {
				String amount = investmentBean.getUnitPrice().replaceAll(",", "");
				double d = Double.parseDouble(amount);
				customerInvestment.setIssuedUnitPrice(BigDecimal.valueOf(d));
			}
			if (investmentBean.getNoOfUnits() != null) {
				String amount = investmentBean.getNoOfUnits().replaceAll(",", "");
				double d = Double.parseDouble(amount);
				customerInvestment.setNoOfIssuedUnit(BigDecimal.valueOf(d));
				customerInvestment.setBalanceUnits(BigDecimal.valueOf(d));
			}
		}
		return customerInvestment;
	}

	public List<RedemptionInvestmentDto> getCustomerInvestment(int customer_id, int fund_id) {

		PledgeDaoImpl pledgeDaoImpl = new PledgeDaoImpl();
		List<InvestmentForPledge> forPledges = pledgeDaoImpl.getInvestmentByFund(fund_id, customer_id);
		List<RedemptionInvestmentDto> dtos = new ArrayList<RedemptionInvestmentDto>();
		for (InvestmentForPledge investmentForPledge : forPledges) {
			RedemptionInvestmentDto dto = new RedemptionInvestmentDto();

			CustomerInvestment customerInvestment = investmentForPledge.getCustomerInvestment();
			if (customerInvestment.getStatus().equals("CONFIRM")) {
				// Investment Date
				if (customerInvestment.getIssuedDate() != null)
					dto.setConfirmDate(format.format(customerInvestment.getIssuedDate()));
				// Invested Amount
				dto.setAmount(customerInvestment.getAmount());
				// Invested Units
				dto.setNoOfUnits(customerInvestment.getNoOfIssuedUnit());

				dto.setFund_id(customerInvestment.getFund().getId());
				// Current fund unit price
				dto.setUnitPrice(customerInvestment.getFund().getUnitValue());

				dto.setCustomer(investmentForPledge.getCustomer().getId());
				dto.setInvenstmentCode(customerInvestment.getInvenstmentCode());
				dto.setInvestmentId(customerInvestment.getId());

				dto.setReleaseAmount(BigDecimal.ZERO);
				dto.setReleaseUnits(BigDecimal.ZERO);
				dto.setRemainingUnits(investmentForPledge.getTotalUnits());

				dtos.add(dto);
			}
		}
		return dtos;
	}

	public InvestmentDto getInvestmentByCode(String investment_code, InvestmentDto investmentDto) {
		CustomerInvestment customerInvestment = daoImpl.getInvesmentByCode(investment_code);
		investmentDto.setId(customerInvestment.getId());
		investmentDto.setCustomer(customerInvestment.getCustomer().getId());
		investmentDto.setCustomerObj(customerInvestment.getCustomer());
		investmentDto.setInvenstmentCode(customerInvestment.getInvenstmentCode());
		investmentDto.setFundTransferType(customerInvestment.getFundTransferType().toString());
		investmentDto.setStatus(customerInvestment.getStatus());
		investmentDto.setRequestDate(format.format(customerInvestment.getRequestDate()));
		investmentDto.setDepositTo(customerInvestment.getDepositTo().toString());
		investmentDto.setAmount(customerInvestment.getAmount().toString());
		investmentDto.setAccountNo(customerInvestment.getCustomerBankAccount().getId());
		investmentDto.setFund_id(customerInvestment.getFund().getId());
		investmentDto.setFullRedemption(customerInvestment.getFullRedemption());
		if (customerInvestment.getFullRedemptionDate() != null)
			investmentDto.setFullRedemptionDate(format.format(customerInvestment.getFullRedemptionDate()));
		investmentDto.setMonthlyInterestRequired(customerInvestment.getMonthlyInterestRequired());
		if (customerInvestment.getMonIntStartDate() != null)
			investmentDto.setMonIntStartDate(format.format(customerInvestment.getMonIntStartDate()));
		investmentDto.setNoOfUnits(customerInvestment.getNoOfIssuedUnit().toString());
		investmentDto.setUnitPrice(customerInvestment.getIssuedUnitPrice().toString());
		if (customerInvestment.getIssuedDate() != null)
			investmentDto.setConfirmDate(format.format(customerInvestment.getIssuedDate()));
		investmentDto.setNameOfBank(customerInvestment.getNameOfBank());
		investmentDto.setBranch(customerInvestment.getBranch());
		investmentDto.setChequeNo(customerInvestment.getChequeNo());
		if (customerInvestment.getChequeDate() != null)
			investmentDto.setChequeDate(format.format(customerInvestment.getChequeDate()));
		investmentDto.setRecodUser(customerInvestment.getRecodeUser().getId());
		if (customerInvestment.getRecodeDate() != null)
			investmentDto.setRequestDate(format.format(customerInvestment.getRecodeDate()));
		if (customerInvestment.getInstructions() != null)
			investmentDto.setInstructions(customerInvestment.getInstructions());
		return investmentDto;
	}

	public void rejectInvestment(int investment_id, InvestmentDto investmentBean) {
		CustomerInvestment customerInvestment = daoImpl.getById(investment_id);
		if (customerInvestment == null) {
			investmentBean.setSuccess(false);
			investmentBean.setResulteMsg("Investment Code already exists");
		} else {
			customerInvestment.setStatus("REJECT");
			daoImpl.rejectInvestment(customerInvestment);
			investmentBean.setSuccess(true);
			investmentBean.setResulteMsg("SUCCESS");
		}

	}

	public List<InvestmentDto> getConfirmedInvestments() {

		List<CustomerInvestment> customerInvestments = daoImpl.getConfirmInvestmentList();
		List<InvestmentDto> investmentBeans = new ArrayList<InvestmentDto>();
		InvestmentDto investment = null;
		for (CustomerInvestment customerInvestment : customerInvestments) {
			investment = new InvestmentDto();
			investment.setId(customerInvestment.getId());
			investment.setAmount(customerInvestment.getAmount().toString());
			investment.setInvenstmentCode(customerInvestment.getInvenstmentCode());
			investment.setStatus(customerInvestment.getStatus());

			investment.setCustomer(customerInvestment.getCustomer().getId());
			investment.setCustomer_code(customerInvestment.getCustomer().getCode());
			if (customerInvestment.getCustomer().getDenotedByInitials() != null) {
				investment.setCustomer_name(customerInvestment.getCustomer().getDenotedByInitials() + " " + customerInvestment.getCustomer().getSurname());
			} else {
				investment.setCustomer_name(customerInvestment.getCustomer().getSurname());
			}
			investment.setPostAddress(customerInvestment.getPostAddress());
			investment.setPostStatus(customerInvestment.getPostStatus());
			if (customerInvestment.getFund() != null) {
				investment.setFund_id(customerInvestment.getFund().getId());
				if (customerInvestment.getIssuedDate() != null)
					investment.setConfirmDate(format.format(customerInvestment.getIssuedDate()));
				if (customerInvestment.getIssuedUnitPrice() != null)
					investment.setUnitPrice(customerInvestment.getIssuedUnitPrice().toString());
				if (customerInvestment.getNoOfIssuedUnit() != null)
					investment.setNoOfUnits(customerInvestment.getNoOfIssuedUnit().toString());
			}

			investmentBeans.add(investment);
		}

		return investmentBeans;

	}

	public void updateStatus(int investment_id, InvestmentDto investmentBean, String addressType) {
		CustomerInvestment customerInvestment = daoImpl.getById(investment_id);
		if (customerInvestment == null) {
			investmentBean.setSuccess(false);
			investmentBean.setResulteMsg("Investment Code already exists");
		} else {
			customerInvestment.setPostStatus("SEND");
			customerInvestment.setPostAddress(addressType);
			daoImpl.updateInvestment(customerInvestment);
			investmentBean.setSuccess(true);
			investmentBean.setResulteMsg("SUCCESS");
		}
	}

	public void cancellation(int investment_id, InvestmentDto investmentBean) {
		if (investment_id != 0) {
			CustomerInvestment customerInvestment = daoImpl.getById(investment_id);
			if (customerInvestment != null) {
				Receipt receipt = null;
				customerInvestment.setStatus("CANCEL");

				List<MoneyTransaction> moneyTransactions = moneyTransactionModel.getTransactionReverse(customerInvestment);
				CustomerTransactionLog customerTransactionLog = createTransactionLogRev(customerInvestment);
				List<CustomerRedemptionRequest> redemptionRequests = redemptionDaoImpl.getRequestByinvestment(customerInvestment.getId());
				for (CustomerRedemptionRequest customerRedemptionRequest : redemptionRequests) {
					if (customerRedemptionRequest.getStatus().equals("CONFIRM")) {
						List<MoneyTransaction> transactions = moneyTransactionModel.getRedemptionReversTranasactions(customerRedemptionRequest);
						moneyTransactions.addAll(transactions);
					}
				}

				if (customerInvestment.getReceipt() != null) {
					receipt = customerInvestment.getReceipt();
					if (receipt.getStatus() == (byte) 1) {
						List<MoneyTransaction> transactions = moneyTransactionModel.getReceiptReversTranasactions(receipt);
						moneyTransactions.addAll(transactions);
					}
					receipt.setStatus((byte) 2);
					receipt.setConfDate(new Date());
					receipt.setPurpose("Investment Cancellation");
					receipt.setConfUserId(LoginAction.getCurrentLogingUser().getId());
				}

				daoImpl.cancelInvestment(customerInvestment, moneyTransactions, redemptionRequests, receipt, customerTransactionLog);
				investmentBean.setSuccess(true);
				investmentBean.setResulteMsg("Success");
			}

		} else {
			investmentBean.setSuccess(false);
			investmentBean.setResulteMsg("There is some error returned from the server.");
		}

	}

	private CustomerTransactionLog createTransactionLogRev(CustomerInvestment customerInvestment) {
		CustomerTransactionLog customerTransactionLog = new CustomerTransactionLog();
		customerTransactionLog.setCustomer(customerInvestment.getCustomer());
		customerTransactionLog.setFund(customerInvestment.getFund());
		customerTransactionLog.setTranType("INVESTMENT");
		customerTransactionLog.setTranUnits(customerInvestment.getNoOfIssuedUnit().negate());
		customerTransactionLog.setCustomerInvestment(customerInvestment);
		customerTransactionLog.setUser(LoginAction.getCurrentLogingUser());
		return customerTransactionLog;
	}

	public List<InvestmentDto> getUnConfirmedCheques() {

		List<CustomerInvestment> customerInvestments = daoImpl.getUnConfirmChequeList();
		List<InvestmentDto> investmentBeans = new ArrayList<InvestmentDto>();
		InvestmentDto investment = null;
		for (CustomerInvestment customerInvestment : customerInvestments) {
			investment = new InvestmentDto();
			investment.setId(customerInvestment.getId());
			investment.setAmount(customerInvestment.getAmount().toString());
			investment.setInvenstmentCode(customerInvestment.getInvenstmentCode());
			investment.setStatus(customerInvestment.getStatus());

			investment.setCustomer(customerInvestment.getCustomer().getId());
			investment.setCustomer_code(customerInvestment.getCustomer().getCode());
			if (customerInvestment.getCustomer().getDenotedByInitials() != null) {
				investment.setCustomer_name(customerInvestment.getCustomer().getDenotedByInitials() + " " + customerInvestment.getCustomer().getSurname());
			} else {
				investment.setCustomer_name(customerInvestment.getCustomer().getSurname());
			}
			if (customerInvestment.getFund() != null) {
				investment.setFund_id(customerInvestment.getFund().getId());
				investment.setFundcode(customerInvestment.getFund().getFundCode());
				if (customerInvestment.getIssuedDate() != null)
					investment.setConfirmDate(format.format(customerInvestment.getIssuedDate()));
				if (customerInvestment.getIssuedUnitPrice() != null)
					investment.setUnitPrice(customerInvestment.getFund().getUnitValue().toString());
				if (customerInvestment.getNoOfIssuedUnit() != null)
					investment.setNoOfUnits(customerInvestment.getAmount().divide(customerInvestment.getFund().getUnitValue()).toString());
			}
			if (customerInvestment.getChequeDate() != null) {
				investment.setChequeDate(format.format(customerInvestment.getChequeDate()));
			}
			investment.setChequeNo(customerInvestment.getChequeNo());
			investmentBeans.add(investment);
		}

		return investmentBeans;

	}

	public void confirmCheque(InvestmentDto investmentBean, String investments) {
		if (investments != null) {
			investments = "{ \"investments\" : ".concat(investments) + " }";
			try {
				JSONObject jsonObject = new JSONObject(investments);
				JSONArray jArray = jsonObject.getJSONArray("investments");
				for (int i = 0; i < jArray.length(); i++) {
					JSONObject jObj = jArray.getJSONObject(i);
					CustomerInvestment investment = daoImpl.getById(jObj.getInt("id"));
					investment = createInvetment(investment);

					List<MoneyTransaction> moneyTransactions = moneyTransactionModel.getInvestmetTransaction(format.format(investment.getFund().getUpdateDate()),
							investment.getId(), investment.getAmount().toString(), investment.getCustomer().getId(), investment.getFund().getId());

					/* Create Full Redemption Request */
					CustomerRedemptionRequest redemptionRequest = null;
					if (investment.getFullRedemption() == 1) {
						redemptionRequest = createRedemtioReqest(investment);
					}

					/* Create Monthly Redemption Request */
					CustomerRedemptionRequest monthlyRedempRequest = null;
					if (investment.getMonthlyInterestRequired() == 1) {
						NextDate nextDate = new NextDate();
						monthlyRedempRequest = createMonthlyRedemtioReqest(investment);
						investment.setMonIntNextDate(nextDate.getNextDate(investment.getMonIntStartDate(), investment.getInterestType()));
					}
					/* Customer Transaction log */
					CustomerTransactionLog customerTransactionLog = createTransactionLog(investment);

					daoImpl.confirmCustomerInvestment(investment, moneyTransactions, redemptionRequest, null, monthlyRedempRequest, customerTransactionLog);
					investmentBean.setSuccess(true);
					investmentBean.setResulteMsg("SUCCESS");
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}

	}

	private CustomerInvestment createInvetment(CustomerInvestment investment) {
		if (investment != null) {
			investment.setStatus("CONFIRM");
			investment.setIssuedUser(LoginAction.getCurrentLogingUser());
			if (investment.getFund() != null) {
				investment.setIssuedDate(investment.getFund().getUpdateDate());
				investment.setIssuedUnitPrice(investment.getFund().getUnitValue());
				investment.setNoOfIssuedUnit(investment.getAmount().divide(investment.getFund().getUnitValue()));
				investment.setBalanceUnits(investment.getAmount().divide(investment.getFund().getUnitValue()));
			}
		}
		return investment;
	}
}
